package com.liu.hooks;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import android.annotation.SuppressLint;
import android.content.ContentValues;

import com.liu.util.TrackerLoger;

import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;

public class DataBaseHook extends AbstractHook {
	public static final String TAG = "#DataBaseHook#";
	public static final String TYPE ="com.liu.hooks.DataBaseHook";
			
		XC_MethodHook DataBaseInsertHook = new XC_MethodHook() {

			@SuppressLint("NewApi")
			@Override
			protected void afterHookedMethod(MethodHookParam param)
					throws Throwable {
				// TODO Auto-generated method stub
				String tableName = null;
				String columnName = null;
				ContentValues cv = null;
				tableName = (String) param.args[0];
				if (param.args[1] != null) {
					columnName = (String) param.args[1];
				}
				cv = (ContentValues) param.args[2];
				Set<String> keySet = cv.keySet();
				Set<String> valuesSet = getContentValueValue(cv);
				Iterator<String> keyIt = keySet.iterator();
				Iterator<String> valueIt = valuesSet.iterator();
				for(;keyIt.hasNext();){
					String key = keyIt.next();
					String value = valueIt.next();
					synchronized (this) {		
						TrackerLoger.log(TAG, "dataBaseInsertInfo:"+"TableName:"+tableName+" columnName:"+columnName
								+" key:"+key+" value:"+value,TYPE,true);
					}
				}
				
			}
			
		};
		XC_MethodHook dataBaseDeleteHook = new XC_MethodHook() {

			@Override
			protected void afterHookedMethod(MethodHookParam param)
					throws Throwable {
				// TODO Auto-generated method stub
				String tableName = (String)param.args[0];
				String whereClause =(String)param.args[1];
				synchronized (this) {		
					TrackerLoger.log(TAG, "dataBasedeleteInfo:"+"TableName:"+tableName+" whereClause:"+whereClause,TYPE,true);
				}
			}
		};
		XC_MethodHook dataBaseExecHook = new XC_MethodHook() {

			@Override
			protected void afterHookedMethod(MethodHookParam param)
					throws Throwable {
				// TODO Auto-generated method stub
				String sql = (String)param.args[0];
				Object[] oj = null;
				if(param.args.length == 2){
					 oj = (Object[]) param.args[1];
				}
				if(oj != null){
					synchronized (this) {
						for (Object bindArg : oj) {
							String bind = bindArg.toString();
							TrackerLoger.log(TAG, "dataBasedeExecInfo:"+"sql:"+sql+" bindArg:"+bind,TYPE,true);
						}
					}
				}else{
					TrackerLoger.log(TAG, "dataBasedeExecInfo:"+"sql:"+sql+" bindArg:null",TYPE,true);
				}
			}
		};
		XC_MethodHook dataBaseUpdateHook = new XC_MethodHook() {

			@SuppressLint("NewApi")
			@Override
			protected void afterHookedMethod(MethodHookParam param)
					throws Throwable {
				// TODO Auto-generated method stub
				String tableName = (String)param.args[0];
				ContentValues cv = (ContentValues)param.args[1];
				Set<String> keySet = cv.keySet();
				Set<String> valueSet = getContentValueValue(cv);
				Iterator<String> keyIt = keySet.iterator();
				Iterator<String> valueIt = valueSet.iterator();
				String whereClause = (String)param.args[2];
				for(;keyIt.hasNext();){
					String key = keyIt.next();
					String value = valueIt.next();
					synchronized (this) {		
						TrackerLoger.log(TAG, "dataBaseUpdateInfo:"+"TableName:"+tableName+" whereClause:"+whereClause
								+" key:"+key+" value:"+value,TYPE,true);
					}
				}
				
			}
			
		};
	@Override
	public void doHook() {
		// TODO Auto-generated method stub
		XposedHelpers.findAndHookMethod("android.database.sqlite.SQLiteDatabase",classloader,
				"insert",String.class,String.class,ContentValues.class,DataBaseInsertHook);
		XposedHelpers.findAndHookMethod("android.database.sqlite.SQLiteDatabase", classloader, 
				"delete",String.class,String.class,String[].class,dataBaseDeleteHook);
		XposedHelpers.findAndHookMethod("android.database.sqlite.SQLiteDatabase", classloader, 
				"update",String.class,ContentValues.class,String.class,String[].class,dataBaseUpdateHook);
		XposedBridge.hookAllMethods(android.database.sqlite.SQLiteDatabase.class, "execSQL", dataBaseExecHook);
	}

	@Override
	public void setClassLoader(ClassLoader classloader) {
		// TODO Auto-generated method stub
		this.classloader = classloader;
	}
	@SuppressLint("NewApi")
	public Set<String> getContentValueValue(ContentValues cv){
		Set<String> valueSet = new HashSet<String>();
		Set<String> keySet = cv.keySet();
		Iterator<String> it = keySet.iterator();
		for(;it.hasNext();){
			valueSet.add(cv.getAsString(it.next()));
		}
		return valueSet;
	}
}

	


